package com.batchap.photoframe;

import java.io.IOException;
import java.util.Date;

import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.Item;
import javax.microedition.lcdui.game.GameCanvas;
import javax.microedition.media.Manager;
import javax.microedition.media.MediaException;
import javax.microedition.media.Player;
import javax.microedition.media.control.VideoControl;

import com.batchap.classes.FileSelector;
import com.batchap.classes.ImageUtils;
import com.batchap.classes.MySprite;

public class FrameScreen extends GameCanvas implements Runnable,
		CommandListener {

	MainMIDlet midlet;
	Thread mainThread;

	MySprite[] frameList;
	MySprite currentFrame;
	int currentFrameIndex = 0;
	int capturedImagePositionX = 0;
	int capturedImagePositionY = 0;
	int capturedImageRootPositionX = 0;
	int capturedImageRootPositionY = 0;

	MySprite background;
	MySprite leftPointer, rightPointer;
	MySprite saveButton, switchToLiveView, backToMenu, openGallery;
	// boolean isLiveViewState = false;
	// -----------------------------------------

	Form cameraForm;

	// Player for camera
	private Player player;
	// Video control of camera
	private VideoControl videoControl;
	// Image captured by camera.
	private Image capturedImage;
	// String for capture locator
	private String captureLocator;

	Command shoot, back;
	// -----------------------------------------
	private boolean IsActive = false;
	byte[] imageData;
	public String frameType = "";
	FileSelector fileSelector;
	// -----------------------------------------

	public FrameScreen(final MainMIDlet midlet) {
		// super(true);
		super(false);
		setFullScreenMode(true);
		this.midlet = midlet;
	}

	public void Init() {

		if (fileSelector == null)
			fileSelector = new FileSelector(this);
		try {
			// currentFrame = new
			// MySprite(Image.createImage("/kid/frame0.png"));

			background = new MySprite(Image.createImage("/frame_bg.jpg"));

			leftPointer = new MySprite(
					Image.createImage("/LeftPointer_100x54.png"));
			leftPointer.setPosition(0, 0);

			rightPointer = new MySprite(
					Image.createImage("/RightPointer_100x54.png"));
			rightPointer.setPosition(0, 300);

			saveButton = new MySprite(Image.createImage("/save_40x40.png"));
			saveButton.setPosition(197, 357);

			switchToLiveView = new MySprite(
					Image.createImage("/shoot_40x40.png"));
			switchToLiveView.setPosition(70, 357);
			
			openGallery = new MySprite(
					Image.createImage("/menu/Gallery.png"));
			openGallery.setPosition(135, 357);
			
			backToMenu = new MySprite(Image.createImage("/menu/Menu.png"));
			backToMenu.setPosition(207, 3);
		} catch (IOException ex) {
			ex.printStackTrace();
		}

		// -------------------------
		// ------------------Init Camera----------------

		cameraForm = new Form("Camera");

		// Create commands for this form
		shoot = new Command("Capture", Command.OK, 0);
		back = new Command("Exit", Command.EXIT, 0);
		// Add commands to form
		cameraForm.addCommand(shoot);
		cameraForm.addCommand(back);
		// Set midlet as command listener for this form
		cameraForm.setCommandListener(this);

		try {

			captureLocator = "capture://image";
			// captureLocator = "capture://video";

			player = Manager.createPlayer(captureLocator);
			player.realize();
			player.prefetch();

			videoControl = (VideoControl) player.getControl("VideoControl");

			Item item = (Item) videoControl.initDisplayMode(
					VideoControl.USE_GUI_PRIMITIVE, null);

			// System.out.println("Complete Video 1");
			videoControl.setDisplayFullScreen(true);
			cameraForm.append(item);
			// System.out.println("Complete Video 2");
			player.start();

		} catch (IOException ex) {
			ex.printStackTrace();
		} catch (MediaException ex) {
			ex.printStackTrace();
		}

		// System.out.println("Complete Video");

		// ----------------------------
		IsActive = true;
		mainThread = new Thread(this);
		mainThread.start();
	}

	public void InitFrameType(String frameType) {
		try {
			if (this.frameType.equals(frameType))
			{
				return;
				// không cần reset
			}
			this.frameType = frameType;

			if (frameType.equals("kid")) {
				frameList = null;
				System.gc();
				frameList = new MySprite[PublicAndStatic.nFrameKid];
				currentFrame = new MySprite(
						Image.createImage(PublicAndStatic.frameKidResourcesPath
								+ "0.png"));
			} else if (frameType.equals("flower")) {
				frameList = null;
				System.gc();
				frameList = new MySprite[PublicAndStatic.nFrameFlower];
				currentFrame = new MySprite(
						Image.createImage(PublicAndStatic.frameFlowerResourcesPath
								+ "0.png"));
			}

		} catch (IOException e) {
			e.printStackTrace();
		}

		// Restart Thread
		if (mainThread != null) {
			// mainThread.start();
			//IsActive = true;
			System.out.println("Thread Start");
		}
	}

	public void drawCanvas(Graphics g) {

		try
		{
		//System.out.print("PaintFrame " + g);
		background.Draw(g);
		if (capturedImage != null)
			g.drawImage(capturedImage, capturedImageRootPositionX,
					capturedImageRootPositionY, Graphics.LEFT | Graphics.TOP);

		currentFrame.Draw(g);

		leftPointer.Draw(g);
		rightPointer.Draw(g);
		saveButton.Draw(g);
		switchToLiveView.Draw(g);
		backToMenu.Draw(g);
		openGallery.Draw(g);
		//System.out.print("PaintFrame");
		}
		catch (Exception ex)
		{
			System.out.println("----------------Draw Exception-----------------");			
		}
	}

	public void updateCanvas() {
		// captureImage();
		// System.out.println("Cap");

	}

	private boolean captureImage() {
		try {
			// byte[] imageData;
			// imageData = videoControl.getSnapshot("encoding=bmp");
			imageData = videoControl.getSnapshot(null);
			capturedImage = Image.createImage(imageData, 0, imageData.length);

		} catch (MediaException exc) {
			System.out.println("Err");
			return false;
		} catch (SecurityException secExc) {
			System.out.println("Err");
			return false;
		}
		return true;
	}

	static public void CheckMenmory() {
		Runtime runtime = Runtime.getRuntime();
		runtime.gc();

		System.out.print("-------------------------");
		System.out.print("freeMemory:> " + runtime.freeMemory());
		System.out.print(" totalMemory:> " + runtime.totalMemory());
		System.out.print(" usedMemory:> "
				+ (runtime.totalMemory() - runtime.freeMemory()));
		System.out.println(" %freeMemory:> " + (runtime.freeMemory() * 100 /
		runtime.totalMemory()));
		runtime = null;
	}
	
	protected void pointerPressed(int x, int y) {

		CheckMenmory();
		capturedImagePositionX = x;
		capturedImagePositionY = y;

		if (leftPointer.IsClicked(x, y)) {
			try {
				if (this.frameType.equals("kid")) {
					currentFrameIndex = (currentFrameIndex - 1 + PublicAndStatic.nFrameKid)
							% PublicAndStatic.nFrameKid;

					currentFrame = null;
					System.gc();
					currentFrame = new MySprite(
							Image.createImage(PublicAndStatic.frameKidResourcesPath
									+ currentFrameIndex + ".png"));
				} else if (this.frameType.equals("flower")) {
					currentFrameIndex = (currentFrameIndex - 1 + PublicAndStatic.nFrameFlower)
							% PublicAndStatic.nFrameFlower;

					currentFrame = null;
					System.gc();
					currentFrame = new MySprite(
							Image.createImage(PublicAndStatic.frameFlowerResourcesPath
									+ currentFrameIndex + ".png"));
				}

			} catch (IOException e) {
				e.printStackTrace();
			}

			return;
		}
		if (rightPointer.IsClicked(x, y)) {
			try {
				if (this.frameType.equals("kid")) {
					currentFrameIndex = (currentFrameIndex + 1 + PublicAndStatic.nFrameKid)
							% PublicAndStatic.nFrameKid;

					currentFrame = null;
					System.gc();
					currentFrame = new MySprite(
							Image.createImage(PublicAndStatic.frameKidResourcesPath
									+ currentFrameIndex + ".png"));
				} else if (this.frameType.equals("flower")) {
					currentFrameIndex = (currentFrameIndex + 1 + PublicAndStatic.nFrameFlower)
							% PublicAndStatic.nFrameFlower;

					currentFrame = null;
					System.gc();
					currentFrame = new MySprite(
							Image.createImage(PublicAndStatic.frameFlowerResourcesPath
									+ currentFrameIndex + ".png"));
				}

			} catch (IOException e) {
				e.printStackTrace();
			}
			return;
		}
		if (saveButton.IsClicked(x, y)) {

			Date dateNow = new Date();

			ImageUtils.saveImage2File(ImageUtils.MixFrameAndImage(currentFrame,
					capturedImage, capturedImageRootPositionX,
					capturedImageRootPositionY), "PF_" + dateNow.getTime()
					+ ".png");
			System.out.println("Save");
			return;
		}

		if (switchToLiveView.IsClicked(x, y)) {
			SwitchCameraView(true);
		}
		if (backToMenu.IsClicked(x, y)) {
			// try {
			// mainThread.wait();
			// } catch (InterruptedException e) {
			// e.printStackTrace();
			// }
			//this.IsActive = false;
			this.midlet.switchToMenu();

		}
		if (openGallery.IsClicked(x, y)) {
			System.out.println("Open gallery");
			fileSelector.execute();
			this.midlet.display.setCurrent(fileSelector);
		}
	}

	protected void pointerDragged(int x, int y) {
		capturedImageRootPositionX += x - capturedImagePositionX;
		capturedImageRootPositionY += y - capturedImagePositionY;
		capturedImagePositionX = x;
		capturedImagePositionY = y;

		/*System.out
				.println("Drag: " + x + "-" + y + " - "
						+ capturedImageRootPositionX + "-"
						+ capturedImageRootPositionY);*/
	}

	private void SwitchCameraView(boolean isLiveView) {
		if (isLiveView) {
			midlet.display.setCurrent(cameraForm);
		} else {
			midlet.switchToFrameScreen(this.frameType);
		}
	}

	public void run() {
		Graphics g = getGraphics();
		while (IsActive) {
			System.gc();
			// CheckMenmory();
			updateCanvas();
			drawCanvas(g);
			flushGraphics();
			try {
				Thread.sleep(33);
			} catch (InterruptedException ex) {
				ex.printStackTrace();
			}
		}
	}

	public void commandAction(Command cmd, Displayable dp) {

		if (cmd == back) {
			SwitchCameraView(false);
			System.out.println("Switch: Back");
		}
		if (cmd == shoot) {
			SwitchCameraView(false);
			captureImage();
			capturedImageRootPositionX = 0;
			capturedImageRootPositionY = 0;
			System.out.println("Switch: Capp");

		}
	}

	public void LoadImage(String fileName, byte[] fileData)
	{
		System.out.println("Open: " + fileName);
		//capturedImage = Image.createImage(fileName);
		capturedImage = Image.createImage(fileData, 0, fileData.length);
	}
	public void SwitchToThis()
	{
		System.out.println("Switch: " + this.frameType);
		this.midlet.switchToFrameScreen(this.frameType);
	}
}
